package com.example.libpro.DAO;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.example.libpro.DBEntity.BookEntity;
import com.example.libpro.DBEntity.DBHelper;
import com.example.libpro.DBEntity.DataBaseContext;

import java.util.ArrayList;
import java.util.List;

/**
 * 图书管理系统图书数据访问类（DAO）
 * 作用：1. 封装"book"表的所有CRUD操作，直接对接DBHelper的数据库实例；
 * 2. 实现《安卓设计报告.docx》中"管理员·图书管理"（新增/修改/删除/查询图书）与"读者·图书检索"（查询在库图书）的底层数据操作；
 * 3. 为服务层（BookService）提供图书数据访问接口，支持借还书时的库存更新（报告"借书业务流程-更新图书状态"）。
 * 关联实体：BookEntity（映射"book"表）
 * 依赖：DBHelper（获取SQLite数据库实例）、Android Context（初始化DBHelper）
 * 业务适配：支持在库图书筛选（报告"读者·图书检索-仅显示'在库'图书"）、库存更新（报告借还书时"更新图书状态"）
 */
public class BookDAO {
    private final DBHelper dbHelper;

    // 构造方法：初始化DBHelper
    /**
     * BookDAO构造方法
     * @param context Android上下文对象，用于创建DBHelper实例
     * 功能：建立与SQLite数据库的连接，为图书CRUD操作提供基础
     */
    public BookDAO(Context context) {
        DataBaseContext dbContext = new DataBaseContext(context);
        this.dbHelper = new DBHelper(dbContext);
    }

    // 1. 新增图书（对应报告"管理员·图书管理-书籍添加"）
    /**
     * 新增图书（插入"book"表）
     * @param bookEntity 图书数据实体（含书名、作者、分类、总数量、当前在库数量）
     * @return boolean 操作结果：true=新增成功，false=新增失败（如数据不合法）
     * 业务适配：符合报告"添加新增书籍信息"流程；
     * 数据校验：1. 书名（bookName）、作者（author）、分类（category）非空；2. 总数量（totalCount）≥1；3. 当前在库数量（currentStock）≤总数量
     */
    public boolean insertBook(BookEntity bookEntity) {
        SQLiteDatabase db = null;
        try {
            // 基础数据校验（避免非法数据插入）
            if (bookEntity.getBookName() == null || bookEntity.getAuthor() == null || bookEntity.getCategory() == null) {
                return false;
            }
            if (bookEntity.getTotalCount() < 1 || bookEntity.getCurrentStock() > bookEntity.getTotalCount()) {
                return false;
            }

            db = dbHelper.getWritableDB();
            ContentValues values = new ContentValues();
            values.put("book_name", bookEntity.getBookName());
            values.put("author", bookEntity.getAuthor());
            values.put("category", bookEntity.getCategory());
            values.put("total_count", bookEntity.getTotalCount());
            values.put("current_stock", bookEntity.getCurrentStock());
            values.put("is_deleted", 0); // 初始为未删除状态

            long rowId = db.insert("book", null, values);
            return rowId != -1;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    // 2. 修改图书信息（对应报告"管理员·图书管理-书籍修改"）
    /**
     * 修改图书信息（更新"book"表）
     * @param bookEntity 图书数据实体（需含bookId，其他属性为待修改值）
     * @return boolean 操作结果：true=修改成功，false=修改失败（如图书不存在）
     * 业务适配：符合报告"修改现有书籍信息"流程；
     * 支持修改项：书名（bookName）、作者（author）、分类（category）、总数量（totalCount）；
     * 注意事项：修改总数量时，需确保当前在库数量（currentStock）≤新总数量，避免数据矛盾
     */
    public boolean updateBook(BookEntity bookEntity) {
        SQLiteDatabase db = null;
        try {
            db = dbHelper.getWritableDB();
            ContentValues values = new ContentValues();
            if (bookEntity.getBookName() != null) values.put("book_name", bookEntity.getBookName());
            if (bookEntity.getAuthor() != null) values.put("author", bookEntity.getAuthor());
            if (bookEntity.getCategory() != null) values.put("category", bookEntity.getCategory());
            if (bookEntity.getTotalCount() != null) {
                // 校验：总数量≥当前在库数量（避免总数量小于已借出数量）
                BookEntity oldBook = queryBookById(bookEntity.getBookId());
                if (oldBook != null && bookEntity.getTotalCount() < oldBook.getCurrentStock()) {
                    return false;
                }
                values.put("total_count", bookEntity.getTotalCount());
            }

            String whereClause = "book_id = ? AND is_deleted = 0";
            String[] whereArgs = {String.valueOf(bookEntity.getBookId())};

            int affectedRows = db.update("book", values, whereClause, whereArgs);
            return affectedRows > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    // 3. 逻辑删除图书（对应报告"管理员·图书管理-书籍删除"）
    /**
     * 逻辑删除图书（更新"book"表的is_deleted字段为1）
     * @param bookId 图书ID（对应"book"表的book_id）
     * @return boolean 操作结果：true=删除成功，false=删除失败（如图书不存在或有未还记录）
     * 业务适配：符合报告"删除不存在书籍信息"流程；
     * 前置校验：删除前需确认该图书无未还借阅记录（避免删除后无法追溯借还状态）
     */
    public boolean deleteBook(Integer bookId) {
        SQLiteDatabase db = null;
        try {
            // 前置校验：查询该图书是否有未还记录（borrow_status=0=未还）
            String checkBorrowSql = "SELECT COUNT(*) FROM borrow_record WHERE book_id = ? AND borrow_status = 0";
            db = dbHelper.getReadableDB();
            Cursor cursor = db.rawQuery(checkBorrowSql, new String[]{String.valueOf(bookId)});
            if (cursor.moveToFirst() && cursor.getInt(0) > 0) {
                cursor.close();
                return false; // 存在未还记录，禁止删除
            }
            cursor.close();

            // 执行逻辑删除
            db = dbHelper.getWritableDB();
            ContentValues values = new ContentValues();
            values.put("is_deleted", 1);

            String whereClause = "book_id = ? AND is_deleted = 0";
            String[] whereArgs = {String.valueOf(bookId)};

            int affectedRows = db.update("book", values, whereClause, whereArgs);
            return affectedRows > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    // 4. 多条件查询图书（对应报告"管理员·图书管理-书籍查询"、"读者·图书检索"）
    /**
     * 按书名、作者、分类多条件查询图书（支持模糊匹配，过滤已删除记录）
     * @param bookName 书名关键字（可为null，null时不按书名筛选）
     * @param author 作者关键字（可为null，null时不按作者筛选）
     * @param category 分类（可为null，null时不按分类筛选）
     * @return List<BookEntity> 匹配的图书列表（无匹配时返回空列表）
     * 业务适配：1. 管理员查询：返回所有未删除图书；2. 读者查询：需结合queryInStockBooks筛选在库图书
     */
    public List<BookEntity> queryBookByCondition(String bookName, String author, String category) {
        List<BookEntity> bookList = new ArrayList<>();
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            // 动态拼接查询条件（避免SQL注入，使用参数化查询）
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT book_id, book_name, author, category, total_count, current_stock, is_deleted ");
            sql.append("FROM book ");
            sql.append("WHERE is_deleted = 0 "); // 过滤已删除图书

            List<String> argsList = new ArrayList<>();
            // 拼接书名条件（若不为null）
            if (bookName != null && !bookName.isEmpty()) {
                sql.append("AND book_name LIKE ? ");
                argsList.add("%" + bookName + "%");
            }
            // 拼接作者条件（若不为null）
            if (author != null && !author.isEmpty()) {
                sql.append("AND author LIKE ? ");
                argsList.add("%" + author + "%");
            }
            // 拼接分类条件（若不为null）
            if (category != null && !category.isEmpty()) {
                sql.append("AND category = ? ");
                argsList.add(category); // 分类为精确匹配（非模糊）
            }

            // 执行查询
            String[] selectionArgs = argsList.toArray(new String[0]);
            cursor = db.rawQuery(sql.toString(), selectionArgs);

            // 封装结果集
            while (cursor.moveToNext()) {
                BookEntity book = new BookEntity();
                book.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                book.setBookName(cursor.getString(cursor.getColumnIndexOrThrow("book_name")));
                book.setAuthor(cursor.getString(cursor.getColumnIndexOrThrow("author")));
                book.setCategory(cursor.getString(cursor.getColumnIndexOrThrow("category")));
                book.setTotalCount(cursor.getInt(cursor.getColumnIndexOrThrow("total_count")));
                book.setCurrentStock(cursor.getInt(cursor.getColumnIndexOrThrow("current_stock")));
                book.setIsDeleted(cursor.getInt(cursor.getColumnIndexOrThrow("is_deleted")));
                bookList.add(book);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return bookList;
    }

    // 5. 查询在库图书（对应报告"读者·图书检索-仅显示'在库'图书"）
    /**
     * 查询当前在库的图书（current_stock > 0，且未删除）
     * @param bookName 书名关键字（可为null，null时不筛选书名）
     * @return List<BookEntity> 在库图书列表（无匹配时返回空列表）
     * 业务适配：符合报告"读者·图书检索-仅显示'在库'图书可立即借阅"流程；
     * 核心逻辑：筛选条件为"current_stock > 0"（有可借阅数量）且"is_deleted = 0"（未删除）
     */
    public List<BookEntity> queryInStockBooks(String bookName) {
        List<BookEntity> inStockList = new ArrayList<>();
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            String sql = "SELECT book_id, book_name, author, category, total_count, current_stock, is_deleted " +
                    "FROM book " +
                    "WHERE is_deleted = 0 " +
                    "AND current_stock > 0 " + // 仅在库图书（可借阅）
                    (bookName != null ? "AND book_name LIKE ? " : "");

            String[] selectionArgs = bookName != null ? new String[]{"%" + bookName + "%"} : new String[0];
            cursor = db.rawQuery(sql, selectionArgs);

            while (cursor.moveToNext()) {
                BookEntity book = new BookEntity();
                book.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                book.setBookName(cursor.getString(cursor.getColumnIndexOrThrow("book_name")));
                book.setAuthor(cursor.getString(cursor.getColumnIndexOrThrow("author")));
                book.setCategory(cursor.getString(cursor.getColumnIndexOrThrow("category")));
                book.setTotalCount(cursor.getInt(cursor.getColumnIndexOrThrow("total_count")));
                book.setCurrentStock(cursor.getInt(cursor.getColumnIndexOrThrow("current_stock")));
                book.setIsDeleted(cursor.getInt(cursor.getColumnIndexOrThrow("is_deleted")));
                inStockList.add(book);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return inStockList;
    }

    // 6. 更新图书库存（对应报告"借书业务流程-更新图书状态"、"还书业务流程-更新图书状态"）
    /**
     * 更新图书库存（借书时减1，还书时加1）
     * @param bookId 图书ID
     * @param stockChange 库存变化量：+1=还书（库存增加），-1=借书（库存减少）
     * @return boolean 操作结果：true=更新成功，false=更新失败（如库存不足）
     * 业务适配：符合报告"借书→更新图书状态"、"还书→更新图书状态"流程；
     * 校验逻辑：借书时（stockChange=-1）需确保当前库存≥1，避免库存为负
     */
    public boolean updateBookStock(Integer bookId, int stockChange) {
        SQLiteDatabase db = null;
        try {
            db = dbHelper.getWritableDB();
            // 开启事务（确保库存查询和更新的原子性，避免并发问题）
            db.beginTransaction();

            // 1. 查询当前库存
            String querySql = "SELECT current_stock FROM book WHERE book_id = ? AND is_deleted = 0";
            Cursor cursor = db.rawQuery(querySql, new String[]{String.valueOf(bookId)});
            if (!cursor.moveToFirst()) {
                cursor.close();
                db.endTransaction(); // 无匹配图书，结束事务
                return false;
            }
            int currentStock = cursor.getInt(cursor.getColumnIndexOrThrow("current_stock"));
            cursor.close();

            // 2. 校验库存（借书时库存需≥1）
            if (stockChange == -1 && currentStock < 1) {
                db.endTransaction(); // 库存不足，结束事务
                return false;
            }

            // 3. 计算新库存并更新
            int newStock = currentStock + stockChange;
            ContentValues values = new ContentValues();
            values.put("current_stock", newStock);

            String whereClause = "book_id = ? AND is_deleted = 0";
            String[] whereArgs = {String.valueOf(bookId)};

            int affectedRows = db.update("book", values, whereClause, whereArgs);
            if (affectedRows > 0) {
                db.setTransactionSuccessful(); // 标记事务成功
            }

            return affectedRows > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (db != null && db.inTransaction()) {
                db.endTransaction(); // 结束事务（无论成功与否）
            }
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    // 辅助方法：按ID查询单本图书（供修改、删除时前置校验）
    /**
     * 按图书ID查询单本图书（辅助方法）
     * @param bookId 图书ID
     * @return BookEntity 匹配的图书实体（无匹配时返回null）
     * 功能：为updateBook、deleteBook等方法提供前置数据校验（如图书是否存在）
     */
    public BookEntity queryBookById(Integer bookId) {
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            String sql = "SELECT book_id, book_name, author, category, total_count, current_stock, is_deleted " +
                    "FROM book " +
                    "WHERE book_id = ? AND is_deleted = 0";
            String[] selectionArgs = {String.valueOf(bookId)};

            cursor = db.rawQuery(sql, selectionArgs);
            if (cursor.moveToFirst()) {
                BookEntity book = new BookEntity();
                book.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                book.setBookName(cursor.getString(cursor.getColumnIndexOrThrow("book_name")));
                book.setAuthor(cursor.getString(cursor.getColumnIndexOrThrow("author")));
                book.setCategory(cursor.getString(cursor.getColumnIndexOrThrow("category")));
                book.setTotalCount(cursor.getInt(cursor.getColumnIndexOrThrow("total_count")));
                book.setCurrentStock(cursor.getInt(cursor.getColumnIndexOrThrow("current_stock")));
                book.setIsDeleted(cursor.getInt(cursor.getColumnIndexOrThrow("is_deleted")));
                return book;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return null;
    }
}